[XEN][POWERPC] Create a Domain Foreign Map space
authorJimi Xenidis <jimix@watson.ibm.com>
Sun, 8 Oct 2006 15:34:24 +0000 (11:34 -0400)
committerJimi Xenidis <jimix@watson.ibm.com>
Sun, 8 Oct 2006 15:34:24 +0000 (11:34 -0400)
The following patch creates a Domain Foreign Map space that is uses to
map granted memory into the Linear Map of the domain.  The Linear Map
of Linux is the is the Kernel Virtual address space where VA = PA +
PAGE_OFFSET.
Also:
 - lots of grant_* interfaces work now
 - mm.[ch] cleanups
 - first pass at extracting Page Table operations from PAPR interfaces
 - get_page_type() fix logic bug
 - recognize a grant table mapping by placing its gmfn at the end of
   real memory.
 - grant table usually mapped like an IO page, so force WIMG bits I=0
 - mfn_to_gmfn and pfn2mfn get WAY to complex, need get a simpler model in.
 - communicate the Domain Foreign Map to domains using /xen/foreign-map
 - make sure all bit definitions are UL where possible
 - now that we actually assign Xen heap pages to domains they must be
   relinquished
Signed-off-by: Jimi Xenidis <jimix@watson.ibm.com>
Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com>
xen/arch/powerpc/domain.c
xen/arch/powerpc/mm.c
xen/arch/powerpc/ofd_fixup.c
xen/arch/powerpc/papr/xlate.c
xen/include/asm-powerpc/grant_table.h
xen/include/asm-powerpc/mm.h

index 7d69f72fe9c34a522d03dfac61c21975de474af1..f2fe28048cd63617fef129803cedd4163860b8a7 100644 (file)
@@ -94,6 +94,7 @@ int arch_domain_create(struct domain *d)
 void arch_domain_destroy(struct domain *d)
 {
     shadow_teardown(d);
+    /* shared_info is part of the RMA so no need to release it */
 }
 
 static void machine_fail(const char *s)
@@ -290,6 +291,7 @@ static void relinquish_memory(struct domain *d, struct list_head *list)
 
 void domain_relinquish_resources(struct domain *d)
 {
+    relinquish_memory(d, &d->xenpage_list);
     relinquish_memory(d, &d->page_list);
     free_extents(d);
     return;
index 06341511dad4e9211db40bc037b26cb47bb6fc2b..7d38872d7d835742bff0195d676455469d2a1337 100644 (file)
@@ -41,18 +41,107 @@ struct page_info *frame_table;
 unsigned long max_page;
 unsigned long total_pages;
 
+void __init init_frametable(void)
+{
+    unsigned long p;
+    unsigned long nr_pages;
+    int i;
+
+    nr_pages = PFN_UP(max_page * sizeof(struct page_info));
+
+    p = alloc_boot_pages(nr_pages, 1);
+    if (p == 0)
+        panic("Not enough memory for frame table\n");
+
+    frame_table = (struct page_info *)(p << PAGE_SHIFT);
+    for (i = 0; i < nr_pages; i += 1)
+        clear_page((void *)((p + i) << PAGE_SHIFT));
+}
+
+void share_xen_page_with_guest(
+    struct page_info *page, struct domain *d, int readonly)
+{
+    if ( page_get_owner(page) == d )
+        return;
+
+    /* this causes us to leak pages in the Domain and reuslts in
+     * Zombie domains, I think we are missing a piece, until we find
+     * it we disable the following code */
+    set_gpfn_from_mfn(page_to_mfn(page), INVALID_M2P_ENTRY);
+
+    spin_lock(&d->page_alloc_lock);
+
+    /* The incremented type count pins as writable or read-only. */
+    page->u.inuse.type_info  = (readonly ? PGT_none : PGT_writable_page);
+    page->u.inuse.type_info |= PGT_validated | 1;
+
+    page_set_owner(page, d);
+    wmb(); /* install valid domain ptr before updating refcnt. */
+    ASSERT(page->count_info == 0);
+    page->count_info |= PGC_allocated | 1;
+
+    if ( unlikely(d->xenheap_pages++ == 0) )
+        get_knownalive_domain(d);
+    list_add_tail(&page->list, &d->xenpage_list);
+
+    spin_unlock(&d->page_alloc_lock);
+}
+
+void share_xen_page_with_privileged_guests(
+    struct page_info *page, int readonly)
+{
+        unimplemented();
+}
+
+static int create_grant_va_mapping(
+    unsigned long va, unsigned long frame, struct vcpu *v)
+{
+    if (v->domain->domain_id != 0) {
+        printk("only Dom0 can map a grant entry\n");
+        BUG();
+        return GNTST_permission_denied;
+    }
+    return GNTST_okay;
+}
+
+static int destroy_grant_va_mapping(
+    unsigned long addr, unsigned long frame, struct domain *d)
+{
+    if (d->domain_id != 0) {
+        printk("only Dom0 can map a grant entry\n");
+        BUG();
+        return GNTST_permission_denied;
+    }
+    return GNTST_okay;
+}
+
 int create_grant_host_mapping(
     unsigned long addr, unsigned long frame, unsigned int flags)
 {
-    panic("%s called\n", __func__);
-    return 1;
+    if (flags & GNTMAP_application_map) {
+        printk("%s: GNTMAP_application_map not supported\n", __func__);
+        BUG();
+        return GNTST_general_error;
+    }
+    if (flags & GNTMAP_contains_pte) {
+        printk("%s: GNTMAP_contains_pte not supported\n", __func__);
+        BUG();
+        return GNTST_general_error;
+    }
+    return create_grant_va_mapping(addr, frame, current);
 }
 
 int destroy_grant_host_mapping(
     unsigned long addr, unsigned long frame, unsigned int flags)
 {
-    panic("%s called\n", __func__);
-    return 1;
+    if (flags & GNTMAP_contains_pte) {
+        printk("%s: GNTMAP_contains_pte not supported\n", __func__);
+        BUG();
+        return GNTST_general_error;
+    }
+
+    /* may have force the remove here */
+    return destroy_grant_va_mapping(addr, frame, current->domain);
 }
 
 int steal_page(struct domain *d, struct page_info *page, unsigned int memflags)
@@ -138,7 +227,7 @@ int get_page_type(struct page_info *page, unsigned long type)
         {
             return 0;
         }
-        if ( unlikely(!(x & PGT_validated)) )
+        else if ( unlikely(!(x & PGT_validated)) )
         {
             /* Someone else is updating validation of this page. Wait... */
             while ( (y = page->u.inuse.type_info) == x )
@@ -157,23 +246,6 @@ int get_page_type(struct page_info *page, unsigned long type)
     return 1;
 }
 
-void __init init_frametable(void)
-{
-    unsigned long p;
-    unsigned long nr_pages;
-    int i;
-
-    nr_pages = PFN_UP(max_page * sizeof(struct page_info));
-
-    p = alloc_boot_pages(nr_pages, 1);
-    if (p == 0)
-        panic("Not enough memory for frame table\n");
-
-    frame_table = (struct page_info *)(p << PAGE_SHIFT);
-    for (i = 0; i < nr_pages; i += 1)
-        clear_page((void *)((p + i) << PAGE_SHIFT));
-}
-
 long arch_memory_op(int op, XEN_GUEST_HANDLE(void) arg)
 {
     printk("%s: no PPC specific memory ops\n", __func__);
@@ -311,9 +383,18 @@ ulong pfn2mfn(struct domain *d, ulong pfn, int *type)
     struct page_extents *pe;
     ulong mfn = INVALID_MFN;
     int t = PFN_TYPE_NONE;
+    ulong foreign_map_pfn = 1UL << cpu_foreign_map_order();
 
     /* quick tests first */
-    if (d->is_privileged && cpu_io_mfn(pfn)) {
+    if (pfn & foreign_map_pfn) {
+        t = PFN_TYPE_FOREIGN;
+        mfn = pfn & ~(foreign_map_pfn);
+    } else if (pfn >= max_page && pfn < (max_page + NR_GRANT_FRAMES)) {
+        /* Its a grant table access */
+        t = PFN_TYPE_GNTTAB;
+        mfn = gnttab_shared_mfn(d, d->grant_table, (pfn - max_page));
+    } else if (test_bit(_DOMF_privileged, &d->domain_flags) &&
+               cpu_io_mfn(pfn)) {
         t = PFN_TYPE_IO;
         mfn = pfn;
     } else {
@@ -365,6 +446,43 @@ ulong pfn2mfn(struct domain *d, ulong pfn, int *type)
     return mfn;
 }
 
+unsigned long mfn_to_gmfn(struct domain *d, unsigned long mfn)
+{
+    struct page_extents *pe;
+    ulong cur_pfn;
+    ulong gnttab_mfn;
+    ulong rma_mfn;
+
+    /* grant? */
+    gnttab_mfn = gnttab_shared_mfn(d, d->grant_table, 0);
+    if (mfn >= gnttab_mfn && mfn < (gnttab_mfn + NR_GRANT_FRAMES))
+        return max_page + (mfn - gnttab_mfn);
+
+    /* IO? */
+    if (test_bit(_DOMF_privileged, &d->domain_flags) &&
+        cpu_io_mfn(mfn))
+        return mfn;
+
+    rma_mfn = page_to_mfn(d->arch.rma_page);
+    if (mfn >= rma_mfn &&
+        mfn < (rma_mfn + (1 << d->arch.rma_order)))
+        return mfn - rma_mfn;
+
+    /* Extent? */
+    cur_pfn = 1UL << d->arch.rma_order;
+    list_for_each_entry (pe, &d->arch.extent_list, pe_list) {
+        uint pe_pages = 1UL << pe->order;
+        uint b_mfn = page_to_mfn(pe->pg);
+        uint e_mfn = b_mfn + pe_pages;
+
+        if (mfn >= b_mfn && mfn < e_mfn) {
+            return cur_pfn + (mfn - b_mfn);
+        }
+        cur_pfn += pe_pages;
+    }
+    return INVALID_M2P_ENTRY;
+}
+
 void guest_physmap_add_page(
     struct domain *d, unsigned long gpfn, unsigned long mfn)
 {
index 9ed61c012b91a13c782e2422de4e49fc15512325..816fd1918920614d77e4764b2b2e01d4bcbf9f9d 100644 (file)
@@ -352,6 +352,11 @@ static ofdn_t ofd_xen_props(void *m, struct domain *d, start_info_t *si)
         if (!rtas_entry)
             ofd_prop_add(m, n, "power-control", NULL, 0);
 
+        /* tell dom0 where ranted pages go in the linear map */
+        val[0] = cpu_foreign_map_order();
+        val[1] = max_page;
+        ofd_prop_add(m, n, "foreign-map", val, sizeof (val));
+
         n = ofd_node_add(m, n, console, sizeof (console));
         if (n > 0) {
             val[0] = 0;
index bfc3af9031e571b3dedfc1d18053c1259ee76d4b..1a08215df8cf9c9a24994d91d2a0cb0b578171c0 100644 (file)
@@ -117,11 +117,8 @@ static void pte_tlbie(union pte volatile *pte, ulong ptex)
 
 }
 
-static void h_enter(struct cpu_user_regs *regs)
+long pte_enter(ulong flags, ulong ptex, ulong vsid, ulong rpn)
 {
-    ulong flags = regs->gprs[4];
-    ulong ptex = regs->gprs[5];
-
     union pte pte;
     union pte volatile *ppte;
     struct domain_htab *htab;
@@ -141,13 +138,12 @@ static void h_enter(struct cpu_user_regs *regs)
     htab = &d->arch.htab;
     if (ptex > (1UL << htab->log_num_ptes)) {
         DBG("%s: bad ptex: 0x%lx\n", __func__, ptex);
-        regs->gprs[3] = H_Parameter;
-        return;
+        return H_Parameter;
     }
 
     /* use local HPTE to avoid manual shifting & masking */
-    pte.words.vsid = regs->gprs[6];
-    pte.words.rpn = regs->gprs[7];
+    pte.words.vsid = vsid;
+    pte.words.rpn = rpn;
 
     if ( pte.bits.l ) {        /* large page? */
         /* figure out the page size for the selected large page */
@@ -163,8 +159,7 @@ static void h_enter(struct cpu_user_regs *regs)
         if ( lp_size >= d->arch.large_page_sizes ) {
             DBG("%s: attempt to use unsupported lp_size %d\n",
                 __func__, lp_size);
-            regs->gprs[3] = H_Parameter;
-            return;
+            return H_Parameter;
         }
 
         /* get correct pgshift value */
@@ -180,19 +175,16 @@ static void h_enter(struct cpu_user_regs *regs)
     mfn = pfn2mfn(d, pfn, &mtype);
     if (mfn == INVALID_MFN) {
         DBG("%s: Bad PFN: 0x%lx\n", __func__, pfn);
-        regs->gprs[3] =  H_Parameter;
-        return;
+        return H_Parameter;
     }
 
-    if (mtype == PFN_TYPE_IO) {
+    if (mtype == PFN_TYPE_IO &&!test_bit(_DOMF_privileged, &d->domain_flags)) {
         /* only a privilaged dom can access outside IO space */
-        if ( !d->is_privileged ) {
-            DBG("%s: unprivileged access to physical page: 0x%lx\n",
-                __func__, pfn);
-            regs->gprs[3] =  H_Privilege;
-            return;
-        }
-
+        DBG("%s: unprivileged access to physical page: 0x%lx\n",
+            __func__, pfn);
+        return H_Privilege;
+    }
+    if (mtype == PFN_TYPE_IO) {
         if ( !((pte.bits.w == 0)
              && (pte.bits.i == 1)
              && (pte.bits.g == 1)) ) {
@@ -200,10 +192,14 @@ static void h_enter(struct cpu_user_regs *regs)
                 "w=%x i=%d m=%d, g=%d\n word 0x%lx\n", __func__,
                 pte.bits.w, pte.bits.i, pte.bits.m, pte.bits.g,
                 pte.words.rpn);
-            regs->gprs[3] =  H_Parameter;
-            return;
+            return H_Parameter;
         }
     }
+    if (mtype == PFN_TYPE_GNTTAB) {
+        DBG("%s: Dom[%d] mapping grant table: 0x%lx\n",
+            __func__, d->domain_id, pfn << PAGE_SHIFT);
+        pte.bits.i = 0;
+    }
     /* fixup the RPN field of our local PTE copy */
     pte.bits.rpn = mfn | lp_bits;
 
@@ -224,14 +220,12 @@ static void h_enter(struct cpu_user_regs *regs)
 
         if (unlikely(!get_domain(f))) {
             DBG("%s: Rescinded, no domain: 0x%lx\n",  __func__, pfn);
-            regs->gprs[3] = H_Rescinded;
-            return;
+            return H_Rescinded;
         }
         if (unlikely(!get_page(pg, f))) {
             put_domain(f);
             DBG("%s: Rescinded, no page: 0x%lx\n",  __func__, pfn);
-            regs->gprs[3] = H_Rescinded;
-            return;
+            return H_Rescinded;
         }
     }
 
@@ -288,10 +282,7 @@ static void h_enter(struct cpu_user_regs *regs)
                 : "b" (ppte), "r" (pte.words.rpn), "r" (pte.words.vsid)
                 : "memory");
 
-            regs->gprs[3] = H_Success;
-            regs->gprs[4] = idx;
-
-            return;
+            return idx;
         }
     }
 
@@ -304,7 +295,24 @@ static void h_enter(struct cpu_user_regs *regs)
     if (f != NULL)
         put_domain(f);
 
-    regs->gprs[3] = H_PTEG_Full;
+    return H_PTEG_Full;
+}
+
+static void h_enter(struct cpu_user_regs *regs)
+{
+    ulong flags = regs->gprs[4];
+    ulong ptex = regs->gprs[5];
+    ulong vsid = regs->gprs[6];
+    ulong rpn = regs->gprs[7];
+    long ret;
+
+    ret = pte_enter(flags, ptex, vsid, rpn);
+
+    if (ret >= 0) {
+        regs->gprs[3] = H_Success;
+        regs->gprs[4] = ret;
+    } else
+        regs->gprs[3] = ret;
 }
 
 static void h_protect(struct cpu_user_regs *regs)
@@ -332,7 +340,7 @@ static void h_protect(struct cpu_user_regs *regs)
 
     /* the AVPN param occupies the bit-space of the word */
     if ( (flags & H_AVPN) && lpte.bits.avpn != avpn >> 7 ) {
-        DBG("%s: %p: AVPN check failed: 0x%lx, 0x%lx\n", __func__,
+        DBG_LOW("%s: %p: AVPN check failed: 0x%lx, 0x%lx\n", __func__,
             ppte, lpte.words.vsid, lpte.words.rpn);
         regs->gprs[3] = H_Not_Found;
         return;
@@ -469,11 +477,8 @@ static void h_clear_mod(struct cpu_user_regs *regs)
     }
 }
 
-static void h_remove(struct cpu_user_regs *regs)
+long pte_remove(ulong flags, ulong ptex, ulong avpn, ulong *hi, ulong *lo)
 {
-    ulong flags = regs->gprs[4];
-    ulong ptex = regs->gprs[5];
-    ulong avpn = regs->gprs[6];
     struct vcpu *v = get_current();
     struct domain *d = v->domain;
     struct domain_htab *htab = &d->arch.htab;
@@ -485,29 +490,25 @@ static void h_remove(struct cpu_user_regs *regs)
 
     if ( ptex > (1UL << htab->log_num_ptes) ) {
         DBG("%s: bad ptex: 0x%lx\n", __func__, ptex);
-        regs->gprs[3] = H_Parameter;
-        return;
+        return H_Parameter;
     }
     pte = &htab->map[ptex];
     lpte.words.vsid = pte->words.vsid;
     lpte.words.rpn = pte->words.rpn;
 
     if ((flags & H_AVPN) && lpte.bits.avpn != (avpn >> 7)) {
-        DBG("%s: avpn doesn not match\n", __func__);
-        regs->gprs[3] = H_Not_Found;
-        return;
+        DBG_LOW("%s: AVPN does not match\n", __func__);
+        return H_Not_Found;
     }
 
     if ((flags & H_ANDCOND) && ((avpn & pte->words.vsid) != 0)) {
         DBG("%s: andcond does not match\n", __func__);
-        regs->gprs[3] = H_Not_Found;
-        return;
+        return H_Not_Found;
     }
 
-    regs->gprs[3] = H_Success;
     /* return old PTE in regs 4 and 5 */
-    regs->gprs[4] = lpte.words.vsid;
-    regs->gprs[5] = lpte.words.rpn;
+    *hi = lpte.words.vsid;
+    *lo = lpte.words.rpn;
 
 #ifdef DEBUG_LOW
     /* XXX - I'm very skeptical of doing ANYTHING if not bits.v */
@@ -522,7 +523,7 @@ static void h_remove(struct cpu_user_regs *regs)
         if (!cpu_io_mfn(mfn)) {
             struct page_info *pg = mfn_to_page(mfn);
             struct domain *f = page_get_owner(pg);
-
+            
             if (f != d) {
                 put_domain(f);
                 put_page(pg);
@@ -536,6 +537,27 @@ static void h_remove(struct cpu_user_regs *regs)
             : "memory");
 
     pte_tlbie(&lpte, ptex);
+
+    return H_Success;
+}
+
+static void h_remove(struct cpu_user_regs *regs)
+{
+    ulong flags = regs->gprs[4];
+    ulong ptex = regs->gprs[5];
+    ulong avpn = regs->gprs[6];
+    ulong hi, lo;
+    long ret;
+
+    ret = pte_remove(flags, ptex, avpn, &hi, &lo);
+
+    regs->gprs[3] = ret;
+
+    if (ret == H_Success) {
+        regs->gprs[4] = hi;
+        regs->gprs[5] = lo;
+    }
+    return;
 }
 
 static void h_read(struct cpu_user_regs *regs)
index e573f714a2d0f222cd0139040aa3e62003669057..32920dad0a53e9b865dbd6d994163a4a43ced4a6 100644 (file)
  * Caller must own caller's BIGLOCK, is responsible for flushing the TLB, and
  * must hold a reference to the page.
  */
+extern long pte_enter(ulong flags, ulong ptex, ulong vsid, ulong rpn);
+extern long pte_remove(ulong flags, ulong ptex, ulong avpn,
+                       ulong *hi, ulong *lo);
+
 int create_grant_host_mapping(
     unsigned long addr, unsigned long frame, unsigned int flags);
 int destroy_grant_host_mapping(
@@ -41,8 +45,7 @@ int destroy_grant_host_mapping(
             (d), XENSHARE_writable);                                     \
     } while ( 0 )
 
-#define gnttab_shared_mfn(d, t, i)                      \
-    ((virt_to_maddr((t)->shared) >> PAGE_SHIFT) + (i))
+#define gnttab_shared_mfn(d, t, i) (((ulong)((t)->shared) >> PAGE_SHIFT) + (i))
 
 #define gnttab_shared_gmfn(d, t, i)                     \
     (mfn_to_gmfn(d, gnttab_shared_mfn(d, t, i)))
@@ -61,4 +64,13 @@ static inline void gnttab_clear_flag(unsigned long nr, uint16_t *addr)
     clear_bit(lnr, laddr);
 }
 
+static inline uint cpu_foreign_map_order(void)
+{
+    /* 16 GiB */
+    return 34 - PAGE_SHIFT;
+}
+
+#define GNTTAB_DEV_BUS(f) \
+    ((f) | (1UL << (cpu_foreign_map_order() + PAGE_SHIFT)))
+
 #endif  /* __ASM_PPC_GRANT_TABLE_H__ */
index 89306a3c9544dff1a602b413994582bc685af75c..78886bcc3894867664bc6347864fed7fe8b0aadc 100644 (file)
  * along with this program; if not, write to the Free Software
  * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  *
- * Copyright (C) IBM Corp. 2005
+ * Copyright (C) IBM Corp. 2005, 2006
  *
  * Authors: Hollis Blanchard <hollisb@us.ibm.com>
+ *          Jimi Xenidis <jimix@watson.ibm.com>
  */
 
 #ifndef _ASM_MM_H_
@@ -90,35 +91,35 @@ struct page_extents {
 };
 
  /* The following page types are MUTUALLY EXCLUSIVE. */
-#define PGT_none            (0<<29) /* no special uses of this page */
-#define PGT_RMA             (1<<29) /* This page is an RMA page? */
-#define PGT_writable_page   (7<<29) /* has writable mappings of this page? */
-#define PGT_type_mask       (7<<29) /* Bits 29-31. */
+#define PGT_none            (0UL<<29) /* no special uses of this page */
+#define PGT_RMA             (1UL<<29) /* This page is an RMA page? */
+#define PGT_writable_page   (7UL<<29) /* has writable mappings of this page? */
+#define PGT_type_mask       (7UL<<29) /* Bits 29-31. */
 
  /* Owning guest has pinned this page to its current type? */
 #define _PGT_pinned         28
-#define PGT_pinned          (1U<<_PGT_pinned)
+#define PGT_pinned          (1UL<<_PGT_pinned)
  /* Has this page been validated for use as its current type? */
 #define _PGT_validated      27
-#define PGT_validated       (1U<<_PGT_validated)
+#define PGT_validated       (1UL<<_PGT_validated)
 
  /* 16-bit count of uses of this frame as its current type. */
-#define PGT_count_mask      ((1U<<16)-1)
+#define PGT_count_mask      ((1UL<<16)-1)
 
  /* Cleared when the owning guest 'frees' this page. */
 #define _PGC_allocated      31
-#define PGC_allocated       (1U<<_PGC_allocated)
+#define PGC_allocated       (1UL<<_PGC_allocated)
  /* Set on a *guest* page to mark it out-of-sync with its shadow */
 #define _PGC_out_of_sync     30
-#define PGC_out_of_sync     (1U<<_PGC_out_of_sync)
+#define PGC_out_of_sync     (1UL<<_PGC_out_of_sync)
  /* Set when is using a page as a page table */
 #define _PGC_page_table      29
-#define PGC_page_table      (1U<<_PGC_page_table)
+#define PGC_page_table      (1UL<<_PGC_page_table)
 /* Set when using page for RMA */
 #define _PGC_page_RMA      28
-#define PGC_page_RMA      (1U<<_PGC_page_RMA)
+#define PGC_page_RMA      (1UL<<_PGC_page_RMA)
  /* 29-bit count of references to this frame. */
-#define PGC_count_mask      ((1U<<28)-1)
+#define PGC_count_mask      ((1UL<<28)-1)
 
 #define IS_XEN_HEAP_FRAME(_pfn) (page_to_maddr(_pfn) < xenheap_phys_end)
 
@@ -133,6 +134,13 @@ static inline u32 pickle_domptr(struct domain *domain)
 #define page_get_owner(_p)    (unpickle_domptr((_p)->u.inuse._domain))
 #define page_set_owner(_p,_d) ((_p)->u.inuse._domain = pickle_domptr(_d))
 
+#define XENSHARE_writable 0
+#define XENSHARE_readonly 1
+extern void share_xen_page_with_guest(
+    struct page_info *page, struct domain *d, int readonly);
+extern void share_xen_page_with_privileged_guests(
+    struct page_info *page, int readonly);
+
 extern struct page_info *frame_table;
 extern unsigned long max_page;
 extern unsigned long total_pages;
@@ -218,11 +226,47 @@ typedef struct {
 } vm_assist_info_t;
 extern vm_assist_info_t vm_assist_info[];
 
-#define share_xen_page_with_guest(p, d, r) do { } while (0)
-#define share_xen_page_with_privileged_guests(p, r) do { } while (0)
 
 /* hope that accesses to this will fail spectacularly */
-#define machine_to_phys_mapping ((u32 *)-1UL)
+#undef machine_to_phys_mapping
+#define INVALID_M2P_ENTRY        (~0UL)
+
+/* do nothing, its all calculated */
+#define set_gpfn_from_mfn(mfn, pfn) do { } while (0)
+#define get_gpfn_from_mfn(mfn) (mfn)
+
+extern unsigned long mfn_to_gmfn(struct domain *d, unsigned long mfn);
+
+extern unsigned long paddr_to_maddr(unsigned long paddr);
+
+#define INVALID_MFN (~0UL)
+#define PFN_TYPE_NONE 0
+#define PFN_TYPE_RMA 1
+#define PFN_TYPE_LOGICAL 2
+#define PFN_TYPE_IO 3
+#define PFN_TYPE_FOREIGN 4
+#define PFN_TYPE_GNTTAB 5
+
+extern ulong pfn2mfn(struct domain *d, ulong pfn, int *type);
+static inline unsigned long gmfn_to_mfn(struct domain *d, unsigned long gmfn)
+{
+    int mtype;
+    ulong mfn;
+    
+    mfn = pfn2mfn(d, gmfn, &mtype);
+    if (mfn != INVALID_MFN) {
+        switch (mtype) {
+        case PFN_TYPE_RMA:
+        case PFN_TYPE_LOGICAL:
+            break;
+        default:
+            WARN();
+            mfn = INVALID_MFN;
+            break;
+        }
+    }
+    return mfn;
+}
 
 extern int update_grant_va_mapping(unsigned long va,
                                    unsigned long val,